Skip to content

feat(experimentation): one warehouse connection per environment#7582

Open
Zaimwa9 wants to merge 1 commit into
mainfrom
feat/unique-connection-per-environment
Open

feat(experimentation): one warehouse connection per environment#7582
Zaimwa9 wants to merge 1 commit into
mainfrom
feat/unique-connection-per-environment

Conversation

@Zaimwa9
Copy link
Copy Markdown
Contributor

@Zaimwa9 Zaimwa9 commented May 22, 2026

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Enforce a single active warehouse connection per environment, regardless of warehouse type:

  • Model: Replace unique_active_warehouse_per_type_and_env constraint (scoped to warehouse_type + environment) with unique_active_warehouse_per_env (scoped to environment only)
  • View: The 409 check on create now rejects any new connection if the environment already has one, not just same-type duplicates
  • Serializer: Soft-delete resurrection reuses any deleted connection in the environment (updating its warehouse_type) rather than matching by type
  • Migration: 0003_unique_connection_per_environment removes the old constraint and adds the new one
  • Test: Added test_post__different_type_already_exists__returns_409 to verify cross-type uniqueness

How did you test this code?

Updated tests.

@Zaimwa9 Zaimwa9 requested a review from a team as a code owner May 22, 2026 14:38
@Zaimwa9 Zaimwa9 requested review from gagantrivedi and khvn26 and removed request for a team May 22, 2026 14:38
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs Ignored Ignored May 22, 2026 2:38pm
flagsmith-frontend-preview Ignored Ignored May 22, 2026 2:38pm
flagsmith-frontend-staging Ignored Ignored May 22, 2026 2:38pm

Request Review

@github-actions github-actions Bot added the api Issue related to the REST API label May 22, 2026
@Zaimwa9 Zaimwa9 removed the request for review from khvn26 May 22, 2026 14:39
@github-actions github-actions Bot added the feature New feature or request label May 22, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-e2e:pr-7582 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api-test:pr-7582 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-frontend:pr-7582 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-api:pr-7582 Finished ✅ Results
ghcr.io/flagsmith/flagsmith:pr-7582 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-7582 Finished ✅ Results

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the WarehouseConnection model to restrict each environment to a single active warehouse connection, regardless of its type. This change includes a new migration, updated model constraints, and modified logic in the serializers and views to enforce this rule. Feedback highlights a potential migration failure if existing environments have multiple active connections of different types, necessitating a data migration. Additionally, the resurrection logic in the serializer is flagged as risky for data consistency, as it allows changing the warehouse_type of an existing record; it is suggested to only resurrect records that match the requested type.

Comment on lines +15 to +22
migrations.AddConstraint(
model_name="warehouseconnection",
constraint=models.UniqueConstraint(
condition=models.Q(("deleted_at__isnull", True)),
fields=("environment",),
name="unique_active_warehouse_per_env",
),
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This migration will fail if any environment currently has multiple active warehouse connections of different types. Since the previous constraint (unique_active_warehouse_per_type_and_env) allowed one connection per type, an environment could have both a Snowflake and a Flagsmith connection active. You should include a data migration to resolve these duplicates (e.g., by soft-deleting all but the most recent one) before applying this new constraint.

Comment on lines 57 to +65
environment=environment,
warehouse_type=warehouse_type,
deleted_at__isnull=False,
)
.order_by("-deleted_at")
.first()
)
if existing:
existing.deleted_at = None
existing.warehouse_type = warehouse_type
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Resurrecting a soft-deleted connection and changing its warehouse_type is risky. If the connection's ID is referenced by other models (e.g., experiments), those references will now point to a connection of a different type, leading to data inconsistency. Since the new unique constraint only applies to active records (deleted_at__isnull=True), it is safer to only resurrect records that match the requested warehouse_type and create a new record otherwise.

Suggested change
environment=environment,
warehouse_type=warehouse_type,
deleted_at__isnull=False,
)
.order_by("-deleted_at")
.first()
)
if existing:
existing.deleted_at = None
existing.warehouse_type = warehouse_type
environment=environment,
warehouse_type=warehouse_type,
deleted_at__isnull=False,
)
.order_by("-deleted_at")
.first()
)
if existing:
existing.deleted_at = None

@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.50%. Comparing base (e79f066) to head (8d94b09).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7582   +/-   ##
=======================================
  Coverage   98.50%   98.50%           
=======================================
  Files        1430     1431    +1     
  Lines       54245    54263   +18     
=======================================
+ Hits        53435    53453   +18     
  Misses        810      810           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  32 seconds
commit  8d94b09
info  🔄 Run: #16943 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  43.2 seconds
commit  8d94b09
info  🔄 Run: #16943 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  3 passed

Details

stats  3 tests across 3 suites
duration  49.9 seconds
commit  8d94b09
info  🔄 Run: #16943 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  38.6 seconds
commit  8d94b09
info  🔄 Run: #16943 (attempt 1)

@github-actions
Copy link
Copy Markdown
Contributor

Visual Regression

19 screenshots compared. See report for details.
View full report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant